home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / Timer.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  8.6 KB  |  294 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Timer.java    1.25 98/08/28
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15.  
  16. package javax.swing;
  17.  
  18. import java.util.*;
  19. import java.awt.*;
  20. import java.awt.event.*;
  21. import java.io.Serializable;
  22. import javax.swing.event.EventListenerList;
  23.  
  24.  
  25. /**
  26.  * Object subclass that causes an action to occur at a predefined rate.  For
  27.  * example, an animation object can use a Timer as the trigger for drawing its
  28.  * next frame.  Each Timer has a list of ActionListeners and a delay (
  29.  * the time between <b>actionPerfomed()</b> calls).  When
  30.  * delay milliseconds have passed, a Timer sends the <b>actionPerformed()</b>
  31.  * message to its listeners.  This cycle repeats until
  32.  * <b>stop()</b> is called, or halts immediately if the Jimer is configured
  33.  * to send its message just once.<p>
  34.  * Using a Timer involves first creating it, then starting it using
  35.  * the <b>start()</b> method.
  36.  * <p>
  37.  * <strong>Warning:</strong>
  38.  * Serialized objects of this class will not be compatible with 
  39.  * future Swing releases.  The current serialization support is appropriate
  40.  * for short term storage or RMI between applications running the same
  41.  * version of Swing.  A future release of Swing will provide support for
  42.  * long term persistence.
  43.  *
  44.  * @version 1.25 08/28/98
  45.  * @author Dave Moore
  46.  */
  47. public class Timer implements Serializable
  48. {
  49.     int         initialDelay, delay;
  50.     boolean     repeats = true, coalesce = true;
  51.  
  52.     protected EventListenerList listenerList = new EventListenerList();
  53.  
  54.     boolean  eventQueued = false;
  55.  
  56.     private static boolean logTimers;
  57.  
  58.     Runnable doPostEvent = null;
  59.  
  60.     // These fields are maintained by TimerQueue.
  61.     // eventQueued can also be reset by the TimerQueue, but will only ever
  62.     // happen in applet case when TimerQueues thread is destroyed.
  63.     long expirationTime;
  64.     Timer nextTimer;
  65.     boolean running;
  66.  
  67.     /**
  68.      * Creates a Timer that will notify its listeners every
  69.      * <i>delay</i> milliseconds.
  70.      * @param delay     The number of milliseconds between listener notification
  71.      * @param listener  An initial listener
  72.      * @see #setInitialDelay
  73.      * @see #setRepeats
  74.      */
  75.     public Timer(int delay, ActionListener listener) {
  76.         super();
  77.         this.delay = delay;
  78.         this.initialDelay = delay;
  79.  
  80.         doPostEvent = new DoPostEvent();
  81.  
  82.     addActionListener(listener);
  83.     }
  84.  
  85.     /**
  86.      * DoPostEvent is a runnable class that fires actionEvents to 
  87.      * the listeners on the EventDispatchThread, via invokeLater.
  88.      * @see #post
  89.      */
  90.     class DoPostEvent implements Runnable, Serializable {
  91.        public void run() {
  92.           if (logTimers) {
  93.              System.out.println("Timer ringing: " + Timer.this);
  94.           }
  95.       if(eventQueued) {
  96.          fireActionPerformed(new ActionEvent(Timer.this, 0, null));
  97.          cancelEvent();
  98.          }
  99.        }
  100.  
  101.        Timer getTimer() {
  102.        return Timer.this;
  103.        }
  104.     }
  105.  
  106.     /**
  107.      * Adds an actionListener to the Timer
  108.      */
  109.     public void addActionListener(ActionListener listener) {
  110.         listenerList.add(ActionListener.class, listener);
  111.     }
  112.  
  113.     /**
  114.      * Removes an ActionListener from the Timer.
  115.      */
  116.     public void removeActionListener(ActionListener listener) {
  117.         listenerList.remove(ActionListener.class, listener);
  118.     }
  119.  
  120.     /**
  121.      * Notify all listeners that have registered interest for
  122.      * notification on this event type.  The event instance 
  123.      * is lazily created using the parameters passed into 
  124.      * the fire method.
  125.      * @see EventListenerList
  126.      */
  127.     protected void fireActionPerformed(ActionEvent e) {
  128.     // Guaranteed to return a non-null array
  129.     Object[] listeners = listenerList.getListenerList();
  130.     // Process the listeners last to first, notifying
  131.     // those that are interested in this event
  132.     for (int i = listeners.length-2; i>=0; i-=2) {
  133.         if (listeners[i]==ActionListener.class) {
  134.         ((ActionListener)listeners[i+1]).actionPerformed(e);
  135.         }           
  136.     }
  137.     }
  138.     
  139.     /** Returns the timer queue. */
  140.     TimerQueue timerQueue() {
  141.         return TimerQueue.sharedInstance();
  142.     }
  143.  
  144.     /**
  145.      * Enables or disables the timer log. When enabled, a message
  146.      * is posted to System.out whenever the timer goes off.
  147.      *
  148.      * @param flag  true to enable logging
  149.      * @see #getLogTimers
  150.      */
  151.     public static void setLogTimers(boolean flag) {
  152.         logTimers = flag;
  153.     }
  154.  
  155.     /**
  156.      * Returns true if logging is enabled.
  157.      *
  158.      * @return true if logging is enabled
  159.      * @see #setLogTimers
  160.      */
  161.     public static boolean getLogTimers() {
  162.         return logTimers;
  163.     }
  164.  
  165.     /** Sets the Timer's delay, the number of milliseconds between successive
  166.       * <b>actionPerfomed()</b> messages to its listeners
  167.       * @see #setInitialDelay
  168.       */
  169.     public void setDelay(int delay) {
  170.         TimerQueue queue;
  171.  
  172.         if (delay < 0) {
  173.             throw new RuntimeException("Invalid initial delay: " + delay);
  174.         }
  175.         this.delay = delay;
  176.  
  177.         if (isRunning()) {
  178.             queue = timerQueue();
  179.             queue.removeTimer(this);
  180.             cancelEvent();
  181.             queue.addTimer(this, System.currentTimeMillis() + delay);
  182.         }
  183.     }
  184.  
  185.     /** Returns the Timer's delay.
  186.       * @see #setDelay
  187.       */
  188.     public int getDelay() {
  189.         return delay;
  190.     }
  191.  
  192.     /** Sets the Timer's initial delay.  This will be used for the first
  193.       * "ringing" of the Timer only.  Subsequent ringings will be spaced
  194.       * using the delay property.
  195.       * @see #setDelay
  196.       */
  197.     public void setInitialDelay(int initialDelay) {
  198.         if (initialDelay < 0) {
  199.             throw new RuntimeException("Invalid initial delay: " +
  200.                                           initialDelay);
  201.         }
  202.         this.initialDelay = initialDelay;
  203.     }
  204.  
  205.     /** Returns the Timer's initial delay.
  206.       * @see #setDelay
  207.       */
  208.     public int getInitialDelay() {
  209.         return initialDelay;
  210.     }
  211.  
  212.     /** If <b>flag</b> is <b>false</b>, instructs the Timer to send
  213.       * <b>actionPerformed()</b> to its listeners only once, and then stop.
  214.       */
  215.     public void setRepeats(boolean flag) {
  216.         repeats = flag;
  217.     }
  218.  
  219.     /** Returns <b>true</b> if the Timer will send a <b>actionPerformed()</b>
  220.       * message to its listeners multiple times.
  221.       * @see #setRepeats
  222.       */
  223.     public boolean isRepeats() {
  224.         return repeats;
  225.     }
  226.  
  227.     /** Sets whether the Timer coalesces multiple pending ActionEvent firings.
  228.       * A busy application may not be able
  229.       * to keep up with a Timer's message generation, causing multiple
  230.       * <b>actionPerformed()</b> message sends to be queued.  When processed,
  231.       * the application sends these messages one after the other, causing the
  232.       * Timer's listeners to receive a sequence of <b>actionPerformed()</b>
  233.       * messages with no delay between them. Coalescing avoids this situation
  234.       * by reducing multiple pending messages to a single message send. Timers
  235.       * coalesce their message sends by default.
  236.       */
  237.     public void setCoalesce(boolean flag) {
  238.         coalesce = flag;
  239.     }
  240.  
  241.     /** Returns <b>true</b> if the Timer coalesces multiple pending
  242.       * <b>performCommand()</b> messages.
  243.       * @see #setCoalesce
  244.       */
  245.     public boolean isCoalesce() {
  246.         return coalesce;
  247.     }
  248.  
  249.     /** Starts the Timer, causing it to send <b>actionPerformed()</b> messages
  250.       * to its listeners.
  251.       * @see #stop
  252.       */
  253.     public void start() {
  254.         timerQueue().addTimer(this, System.currentTimeMillis() + getInitialDelay());
  255.     }
  256.  
  257.     /** Returns <b>true</b> if the Timer is running.
  258.       * @see #start
  259.       */
  260.     public boolean isRunning() {
  261.         return timerQueue().containsTimer(this);
  262.     }
  263.  
  264.     /** Stops a Timer, causing it to stop sending <b>actionPerformed()</b>
  265.       * messages to its Target.
  266.       * @see #start
  267.       */
  268.     public void stop() {
  269.         timerQueue().removeTimer(this);
  270.         cancelEvent();
  271.     }
  272.  
  273.     /**
  274.      * Restarts a Timer, canceling any pending firings, and causing
  275.      * it to fire with its initial dely.
  276.      */
  277.     public void restart() {
  278.         stop();
  279.         start();
  280.     }
  281.  
  282.     synchronized void cancelEvent() {
  283.     eventQueued = false;
  284.     }
  285.  
  286.     synchronized void post() {
  287.         if (eventQueued == false) {
  288.         eventQueued = true;
  289.         SwingUtilities.invokeLater(doPostEvent);
  290.     }
  291.     }
  292.  
  293. }
  294.